package com.bwie.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.pojo.Room;
import com.bwie.pojo.Status;
import com.bwie.pojo.Type;
import com.bwie.service.RoomService;
import com.bwie.service.StatusService;
import com.bwie.service.TypeService;
import com.bwie.unit.MessageVo;
import com.bwie.unit.R;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("user")
public class RoomController {


    @Autowired
    private RoomService roomService;

    @Autowired
    private TypeService typeService;

    @Autowired
    private StatusService statusService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 进行列表分页
     * @param room
     * @return
     */
    @PostMapping("roomList")
    public R roomList(@RequestBody Room room){
        Page<Room> roomPage = new Page<>(room.getPageNum(), room.getPageSize());
        Page<Room> pageList = roomService.pageList(roomPage);
        return R.OK(pageList);
    }


    /**
     * 查询房型下拉框
     * @return
     */
    @PostMapping("TypeList")
    public R TypeList(){
        List<Type> list = typeService.list();
        return R.OK(list);
    }

    /**
     * 查询状态下拉框
     * @return
     */
    @PostMapping("StatusList")
    public R StatusList(){
        List<Status> list = statusService.list();
        return R.OK(list);
    }

    /**
     * 进行添加 发送RabbitMQ消息，通知消费者，将房间的信息保存到redis 保证事务ACID属性
     * @param room
     * @return
     */
    @PostMapping("addRoom")
    @Transactional
    public R addRoom(@RequestBody Room room){
        roomService.save(room);
        MessageVo messageVo = new MessageVo();
        String msgId = UUID.randomUUID().toString();
        messageVo.setMsgId(msgId);
        messageVo.setMsgBody(String.valueOf(room));
        stringRedisTemplate.opsForValue().set("roomList", String.valueOf(room),15, TimeUnit.MINUTES);
        rabbitTemplate.convertAndSend("directExchange","add", JSON.toJSONString(messageVo));
        return R.OK();
    }

    /**
     * 使用RabbitMQ削峰，保证消息不重复消费
     * @param msg
     * @param message
     * @param channel
     * @throws IOException
     */
    @RabbitListener
    public void queue(String msg, Message message, Channel channel) throws IOException {
        MessageVo messageVo = JSON.parseObject(msg, MessageVo.class);
        String msgId = messageVo.getMsgId();
        String msgBody = messageVo.getMsgBody();
        if (!stringRedisTemplate.hasKey(msgId)){
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
            return;
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),true);
    }

    /**
     * 使用Rabbitmq保证消息不会丢失
     */
    @PostConstruct
    public void huiDiao(){
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                rabbitTemplate.convertAndSend(s,s1,message);
                System.out.println("失败");
            }
        });
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if (b){
                    System.out.println("成功");
                }else {
                    System.out.println("失败");
                }
            }
        });
    }


}
